[Previous] [Next]

The SSTab Control

The SSTab control permits you to create tabbed dialog boxes almost the same way the TabStrip common control does it. The most important difference between the two controls is that the SSTab control is a real container, so you can place child controls directly on its surface. You can even switch among tabbed pages at design time, making the job of preparing the control much simpler and quicker than with the TabStrip control. Many programmers find it easier to work with the SSTab control because the control doesn't contain dependent objects, and the syntax of properties and events is more straightforward.

The SSTab control is embedded in the TabCtl32.ocx file, which must therefore be distributed with any Visual Basic application that uses this control.

Setting Design-Time Properties

The first thing to do after you drop an SSTab control on a form is to change its Style property from the default 0-ssStyleTabbedDialog value to the more modern 1-ssStylePropertyPage setting, which you can see in Figure 12-10. The tabs are usually displayed on the upper border of the control, but you can change this default setting by using the TabOrientation property.

Click to view at full size.

Figure 12-10. The General tab of the Property Pages dialog box of an SSTab control.

You can add new tabs (or delete existing ones) by typing a value in the TabCount field (which corresponds to the Tabs property), and you can create multiple rows of tabs by setting a suitable value for the TabsPerRow property. After you have created enough tabs, you can use the spin buttons to move from tab to tab and modify each one's TabCaption property. (This property is the only field in the dialog box whose value depends on the Current Tab field.) Tab captions can include & characters to define hot keys for a quick selection.

The TabHeight property is the height in twips of all the tabs in the control. The TabMaxWidth property is the maximum width of a tab. (A zero width means that the tab is just large enough to accommodate its caption.) The WordWrap property must be True to let longer captions wrap around. If ShowFocusRect is True, a focus rectangle is displayed on the tab that has the focus.

Each tab can display a little image. To set it at design time, you first set the current tab in the General page of the Properties dialog box, switch to the Picture tab, click on the Picture property in the leftmost listbox, and then select the bitmap or icon that you want to assign to the current tab. This bitmap can be referenced in code using the TabPicture property.

After you have created the tabs you need, you can place controls on each one of them. This operation is simple because you can select tabs even at design time. But you should be aware of an important detail: From Visual Basic's standpoint, all the controls you place on different tabs are contained in the SSTab control. In other words, the container is the SSTab control, not its tab pages. This has a number of implications—for example, if you have two groups of OptionButton controls on two different tab pages of the SSTab control, you should place each group in a separate Frame or another container, otherwise Visual Basic sees them as a single group.

Run-Time Operations

The main property of the SSTab control is Tab, which returns the index of the tab currently selected by the user. You can also set it to switch to another tab by means of code. The first tab has a 0 index.

Changing a tab's attributes

You don't need to make a tab current to modify its attributes because most properties expect an index. For example, you can read or modify a tab's caption using the TabCaption property, add a picture to a tab using the TabPicture property, enable or disable a tab with the TabEnabled property, and make it visible or invisible using the TabVisible property:

' Change caption and bitmap of the second tab. (Tabs' indexes are 0-based.)
SSTab1.TabCaption(1) = "Information"
' Note: The actual path of this file might be different on your system.
filename = "c:\VisStudio\Common\Graphics\Bitmaps\Assorted\balloon.bmp"
SSTab1.TabPicture(1) = LoadPicture(filename)
' Make the first tab invisible.
SSTab1.TabVisible(0) = False

The Tabs property returns the number of existing tabs:

' Disable all the tabs except the current one.
For i = 0 To SSTab1.Tabs _ 1
    SSTab1.TabEnabled(i) = (i = SSTab1.Tab)
Next

Creating new tabs

You can create new tabs at run time by increasing the value of the Tabs property. You can append the new tab in one place only: following all the existing ones.

SSTab1.Tabs = SSTab1.Tabs + 1
SSTab1.TabCaption(SSTab1.Tabs - 1) = "Summary"

After you've created a new tab, you might want to add new controls to it. You can do that by dynamically creating new controls and then changing their Container properties. The control becomes a child of the tab that's currently selected:

' Create a TextBox control.
Dim txt As TextBox
Set txt = Controls.Add("VB.TextBox", "txt")
' Move it on the new tab. (You must select it first.)
SSTab1.Tab = SSTab1.Tabs - 1
Set txt.Container = SSTab1
txt.Move 400, 800, 1200, 350
txt.Visible = True

Reacting to tab selection

The SSTab control doesn't expose any custom events. The Click event, however, receives the index of the tab that was current previously. You can use this argument to validate the controls on the tab that lost the focus and to reset the Tab property to cancel the focus shift:

Private Sub SSTab1_Click(PreviousTab As Integer)
    Static Active As Boolean
    If Active Then Exit Sub
    ' Prevent recursive calls.
    Active = True
    Select Case PreviousTab
        Case 0
            ' Validate controls on first tab.
            If Text1 = "" Then SSTab1.Tab = 0
        Case 1
            ' Validate controls on the second tab.
            ' ...
    End Select
    Active = False
End Sub

Setting the Tab property in code fires a Click event, so you must protect your code from recursive calls to the event procedure using a Static flag (the Active variable in the previous routine).

Managing the input focus

You should be aware of a couple of issues concerning the way the SSTab control manages the input focus:

The easiest solution to the first problem is to disable all controls that aren't on the current tab so that they don't receive the input focus if the user presses their hot keys. There's no documented way to learn which controls are on which pages, but it's easy to demonstrate that the SSTab control moves off screen all the child controls that don't belong to the current tab; this is achieved by setting a negative value for the Left property of each child. You can temporarily disable all such controls using the following approach:

' This routine can be reused for any SSTab controls in the application.
Sub ChangeTab(SSTab As SSTab)
    Dim ctrl As Control, TabIndex As Long
    TabIndex = 99999          ' A very high value.
    On Error Resume Next

    For Each ctrl In SSTab.Parent.Controls
        If ctrl.Container Is SSTab Then
            If ctrl.Left < -10000 Then
                ctrl.Enabled = False
            Else
                ctrl.Enabled = True
                If ctrl.TabIndex >= TabIndex Then
                    ' This control comes after our best candidate or
                    ' it doesn't support the TabIndex property.
                Else
                    ' This is the best candidate so far to get the focus.
                    TabIndex = ctrl.TabIndex
                    ctrl.SetFocus
                End If
            End If
        End If
    Next
End Sub

' Call from within the Click event procedure.
Private Sub SSTab1_Click(PreviousTab As Integer)
    ChangeTab SSTab1
End Sub

The ChangeTab routine also solves the second problem, mentioned previously, of moving the focus to the current tab. It does this by moving the focus to the control with the lowest value for the TabIndex property among all the child controls on the current tab. The only thing you have to do is assign an increasing value to the TabIndex properties of the child controls of a SSTab control. For more details, see the source code of the demonstration application provided on the companion CD.